interface T {
    a: string
    c: number
}

// 基础类型的联合 是一定能求出结果的

type U = keyof T 

// keyof anything
type T1 = keyof never
type T2 = keyof any
type T3 = keyof void
type T4 = keyof 'a'
type T5 = keyof T
type T51 = keyof {} // never, and `interface Empty {}`
type T52 = keyof object // never
type T53 = keyof (() => void) // never
type T54 = keyof (new () => void) // never, and `class Empty {}`
class MyClass {a: number = 100}
type T55 = keyof  typeof MyClass // prototype

let v = {a:1, b:'abc'}
type T6 = keyof typeof v // 'a' | 'b' 表达式类型: 非联合, 总是求值
type U1 = ({ // 表达式类型: 联合 (T1 | T2 | .. | Tn)
    a: string
    b: string
} | {
    a: string
    c: number
})
type T7 = keyof U1 // 等价于 keyof T1 & keyof T2 ... & keyof Tn

// 索引存取运算中的枚举类型(T[...])
// - 1.检查 ... in (keyof T)
// - 2.T1['a'] | T2['a'] | .. | Tn['a']
enum T10 {
    a,b,c,d='abc'
}
// T10 等价于 
// enum T10 = {a=0,b=1,c=2,d='abc'}
type T11 = keyof T10 // 枚举在TypeScript类型中变现为联合
type T12 = T10['toString']
// T12 等价于 Number['toString'] | String['toString']

// keyof T10 解析 为如下过程
//  1. keyof T10 (T10.a | T10.b | T10.c | T10.d)
//  2. (keyof T10.a) & (keyof T10.b) & (keyof T10.c) & (keyof T10.d)
//  3. (keyof 0) & (keyof 1) & (keyof 2) & (keyof 'abc')
//  4. (keyof Number) & (keyof Number) & (keyof Number) & (keyof String)
//  5. (keyof Number) & (keyof String)
type T111 = Exclude<keyof Number, never>
type T112 = Exclude<keyof String, never>
type T113 = (keyof Number) & (keyof String)  // 'toString' | 'valueOf'



// 带索引签名的接口类型
type T13 = [string, number, 1] // {[key: number]: string | number}
type T131 = Exclude<keyof T13, never> // '0' | '1' | '2'
type T14 = object[] // {[key: number]: object}
type T141 = Exclude<keyof T14, never> 
type T15 = {
    [k: string]: any
    a: 1
    b: 'string'
    3: true
}
type T151 = Exclude<keyof T15, never>  // string | number
type T152 = Pick<T15, keyof T15>
type T153 = Omit<T15, never>

